package m1.server.config.component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import m1.server.config.component.componentInterface.DatabaseInterfaceProvided;
import m1.server.config.component.componentInterface.DatabaseInterfaceRequired;
import m1.server.config.component.port.Query;
import m1.server.config.component.port.QueryReceive;
import m1.server.config.component.port.SecurityManagement;
import m1.server.config.component.port.SecurityManagementReceive;
import m2.component.Component;
import m2.links.InternalBinding;

public class Database extends Component implements Observer{
	
	private static Database database = null;
	private ArrayList<String> datas = new ArrayList<String>();
	private ArrayList<String> clients = new ArrayList<String>();	
	
	/**
	 * 
	 */
	private Database(){
		DatabaseInterfaceProvided databaseInterfaceProvided = new DatabaseInterfaceProvided();
		DatabaseInterfaceRequired databaseInterfaceRequired = new DatabaseInterfaceRequired();
		addComponentInterfaceProvided(databaseInterfaceProvided);
		addComponentInterfaceRequired(databaseInterfaceRequired);
		addProvidedPort(new Query("Query"), new SecurityManagementReceive("SecurityManagementReceive"));
		SecurityManagement securityManagement = new SecurityManagement("SecurityManagement");
		securityManagement.addObserver(this);
		addRequiredPort(new QueryReceive("QueryReceive"), securityManagement);
		databaseInterfaceProvided.buildService();
		databaseInterfaceRequired.buildService();
		initDatas();
		
		//Reception de la requete du client
		//Traitement et retour
		try {
			Method interBindProcessing = this.getClass().getDeclaredMethod("manageMessageContent", String.class);
			InternalBinding internalBindingOut = new InternalBinding();
			internalBindingOut.internalBindingOut( getRequiredPort("SecurityManagement"), interBindProcessing , this, getProvidedPort("Query"));
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}		
				
		InternalBinding internalBindingIn = new InternalBinding();
		internalBindingIn.internalBindingIn( getProvidedPort("SecurityManagementReceive"), null, null, getRequiredPort("QueryReceive"));
		
	}
	
	/**
	 * 
	 * @return
	 */
	public static Database getInstance(){
		if (database == null){
			database = new Database();
		}
		return database;
	}
	
	/**
	 * 
	 */
	private void initDatas(){
		for (int i = 0; i < 10; i ++){
			datas.add("Data"+i);
		}
	}
	
	/**
	 * 
	 * @param dataSearch
	 * @return
	 */
	public String select(Integer dataSearch){
		return datas.get(dataSearch);		
	}
	
	/**
	 * 
	 * @return
	 */
	public ArrayList<String>selectAll(){
		return datas;
	}
	
	/**
	 * 
	 * @param messageContent
	 * @return
	 */
	public String manageMessageContent(String messageContent) {
		String[] connectTest = messageContent.split("_");
		if (connectTest.length > 2){
			if (searchClient(connectTest[2])){
				int i = 0;
				for (String data : datas){
					if (i == Integer.valueOf(connectTest[1])){
						return("Resultat(s) de la requete : " + data);
					}else{
						return("Aucun resultat pour la requete");
					}
				 }
			 }else{
				 return("Connection necessaire");
			 }	
		}else{
			if (searchClient(connectTest[1])){
				return("Client deja connecte");
			}else{
				clients.add(connectTest[1]);
				return("Connection etablie : " + messageContent);
			}
		}	
		return null;
	}

	/**
	 * 
	 * @param clientId
	 * @return
	 */
	private boolean searchClient(String clientId){
		for (String client : clients){
			if (client.equals(clientId)){
				return true;
			}
		}
		return false;
	}
	
	@Override
	public void update(Observable arg0, Object arg1) {		
	}	

}
